package com.mcc.myapplication

fun printMessage() { /*……*/
}

class Message { /*……*/ }

/**
 * 源文件所有内容（无论是类还是函数）都包含在该包内。
 * 所以上例中 printMessage() 的全名是 org.example.printMessage，
 * 而 Message 的全名是 org.example.Message
 */

/**
 * 默认导入
 * 有多个包会默认导入到每个 Kotlin 文件中：
 * kotlin.*
 * kotlin.annotation.*
 * kotlin.collections.*
 * kotlin.comparisons.*
 * kotlin.io.*
 * kotlin.ranges.*
 * kotlin.sequences.*
 * kotlin.text.*
 *
 * JVM:
 * java.lang.*
 * kotlin.jvm.*
 *
 * 如果出现名字冲突，可以使用 as 关键字在本地重命名冲突项来消歧义：
 * import org.example.Message // Message 可访问
 * import org.test.Message as TestMessage // TestMessage 代表“org.test.Message”
 *
 * 关键字 import 并不仅限于导入类；也可用它来导入其他声明：
 * 顶层函数及属性
 * 在对象声明中声明的函数和属性
 * 枚举常量
 */

class A() {
    var value: Int? = null
        get() {
            return field?.plus(1)
        }
        set(v) {
            field = v?.plus(1)
        }

    lateinit var name: String

    init {
        value = 100
    }

    fun print() {
        println("hello $value")
    }
}

open class B {
    protected fun getGood(): String {
        return "good morning"
    }
}

data class PersonData(val name: String, val age: Int)

open class AParent(val name: String, val age: Int) {
    constructor(name: String) : this(name, 18)

    open fun print1() {
        println("AParent print1")
    }

    // 如何定义内部类
    inner class InnChild {
        fun print() {
            println(this@AParent.name)
        }
    }

}

class AChild : AParent {
    constructor(name: String) : super(name)

    override fun print1() {
        super.print1()
        println("AChild print1")
    }
}

interface MyInterface {
    fun test() {
        println("MyInterface test function")
    }
}

interface MyInterfaceB {
    fun test() {
        println("MyInterfaceB test function")
    }
}

class ImplClass : AParent("王武"), MyInterface, MyInterfaceB {
    override fun test() {
        super<MyInterface>.test()
    }

}

fun main() {
    val a = A()
    a.print()
    a.value = 10
    a.print()

    val c = AChild("张三")
    println(c.name)
    c.print1()

    // 内部类的使用
    AParent("里斯", 29).InnChild().print()

    ImplClass().test()

    val p = PersonData("栅栏", 12)
    p.name
}